﻿using Storage.Admin.Framework.Controllers;
using Storage.Core;
using Storage.Core.Librs;
using Storage.Mapping.AppStorage;
using Storage.Services.AppStorage;
using Storage.Services.Bucket;
using Storage.Services.BucketCut;
using Storage.Services.BucketImages;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;

namespace Storage.Admin.Controllers
{
    public class HomeController : BaseController
    {
        // GET: Home

        private IBucketImagesService _bucketImagesService;
        private IBucketService _bucketService;
        private IAppStorageService _appStorageService;
        private IBucketCutService _bucketCutService;

        public HomeController(IBucketImagesService bucketImagesService,
            IBucketService bucketService,
            IAppStorageService appStorageService,
            IBucketCutService bucketCutService)
        {
            this._bucketCutService = bucketCutService;
            this._bucketImagesService = bucketImagesService;
            this._bucketService = bucketService;
            this._appStorageService = appStorageService;
        }

        public ActionResult Index()
        {
            return View();
        }



        /// <summary>
        /// 获取图片并对图片处理
        /// </summary>
        /// <param name="bucket">桶名称</param>
        /// <param name="name">图片名称</param>
        /// <param name="resize">缩略图选项</param>
        /// <param name="watermark">水印选项 。1：添加水印，其它否</param>
        /// <returns></returns>
        [Route("cn/{bucket}/{name}")]
        public ActionResult JpgImage(string bucket, string name, string resize, string watermark)
        {
            if (String.IsNullOrEmpty(bucket) || String.IsNullOrEmpty(name))
                return HttpNotFound();
            string path = "/" + bucket + "/" + name;
            return getImage(path, bucket, resize, watermark);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bucket"></param>
        /// <param name="subdirectory1"></param>
        /// <param name="name"></param>
        /// <param name="resize"></param>
        /// <param name="watermark"></param>
        /// <returns></returns>
        [Route("cn/{bucket}/{subdirectory1}/{name}")]
        public ActionResult JpgImage(string bucket, string subdirectory1, string name, string resize, string watermark)
        {
            if (String.IsNullOrEmpty(bucket) || String.IsNullOrEmpty(name) || String.IsNullOrEmpty(subdirectory1))
                return HttpNotFound();
            string path = "/" + bucket + "/" + subdirectory1 + "/" + name;
            return getImage(path, bucket, resize, watermark);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bucket"></param>
        /// <param name="subdirectory1"></param>
        /// <param name="subdirectory2"></param>
        /// <param name="name"></param>
        /// <param name="resize"></param>
        /// <param name="watermark"></param>
        /// <returns></returns>
        [Route("cn/{bucket}/{subdirectory1}/{subdirectory2}/{name}")]
        public ActionResult JpgImage(string bucket, string subdirectory1, string subdirectory2, string name, string resize, string watermark)
        {
            if (String.IsNullOrEmpty(bucket) || String.IsNullOrEmpty(name) || String.IsNullOrEmpty(subdirectory1) || String.IsNullOrEmpty(subdirectory2))
                return HttpNotFound();
            string path = "/" + bucket + "/" + subdirectory1 + "/" + subdirectory2 + "/" + name;
            return getImage(path, bucket, resize, watermark);
        }

        #region

        /// <summary>
        /// 获取图片
        /// </summary>
        /// <param name="relativeUrl"></param>
        /// <param name="bucket"></param>
        /// <param name="resize"></param>
        /// <param name="watermark"></param>
        /// <returns></returns>
        private ActionResult getImage(string relativeUrl, string bucket, string resize, string watermark)
        {
            relativeUrl = relativeUrl.ToLower();
            string cutUrl = relativeUrl;
            if (!String.IsNullOrEmpty(resize) || !String.IsNullOrEmpty(watermark))
            {
                if (!String.IsNullOrEmpty(resize))
                {
                    cutUrl += "?resize=" + resize;
                }
                if (!String.IsNullOrEmpty(watermark))
                {
                    if (cutUrl.IndexOf('?') > -1)
                    {
                        cutUrl += "&watermark=1";
                    }
                    else
                        cutUrl += "?watermark=1";
                }
                var cutItem = _bucketImagesService.getBacketImage(cutUrl);
                if (cutItem != null)
                {
                    cutItem.IOPath = cutItem.IOPath.TrimStart('~');
                    string path = WebHelper.mapPath(cutItem.IOPath);
                    if (System.IO.File.Exists(path))
                    {
                        using (Image image = Image.FromFile(path))
                        {
                            return imageResult(image, cutItem.FileName);
                        }
                    }
                }
            }

            if (!String.IsNullOrEmpty(resize))
            {
                var bucketItem = _bucketService.getByName(bucket);
                var cutList = _bucketCutService.getAllCach();
                if (cutList != null)
                {
                    if (!cutList.Any(o => o.BucketId == bucketItem.Id && o.Value == resize))
                    {
                        return HttpNotFound();
                    }
                }
            }

            //获取
            var item = _bucketImagesService.getBacketImage(relativeUrl);
            if (item == null)
                return HttpNotFound();
            string ioPath = item.IOPath.TrimStart('~');
            ioPath = '~' + item.IOPath;
            //绝对路径
            string abPath = WebHelper.mapPath(ioPath);
            try
            {
                using (Image image = Image.FromFile(abPath))
                {
                    Image thum = image;
                    if (!String.IsNullOrEmpty(resize))
                        thum = processSize(thum, resize);
                    if (!String.IsNullOrEmpty(watermark))
                        thum = waterMarkImage(thum, bucket, watermark);
                    //链接不相等
                    if (cutUrl != relativeUrl)
                    {
                        //文件目录
                        string cutDir = System.IO.Path.GetDirectoryName(abPath);
                        string name = Path.GetFileNameWithoutExtension(abPath);
                        name += "_" + resize;
                        if (watermark == "1")
                            name += "_1";
                        //剪裁的文件名
                        string cutFileName = name + Path.GetExtension(abPath);
                        //保存的绝对路径
                        string cutIOPath = Path.Combine(cutDir, cutFileName);
                        //保存图片
                        thum.Save(cutIOPath);
                        using (MemoryStream ms = imageSave(thum, cutFileName))
                        {
                            thum.Save(ms, ImageFormat.Jpeg);
                            string cutSHA1 = FileUitls.GetSHA1(ms);
                            string imagePath = Path.Combine(Path.GetDirectoryName(item.IOPath), cutFileName);
                            var entity = new Entities.BucketImage()
                            {
                                BucketId = item.BucketId,
                                FileName = cutFileName,
                                Length = (int)ms.Length,
                                IOPath = imagePath,
                                RelativeUrl = cutUrl.ToLower(),//访问地址转换小写
                                CreationTime = DateTime.Now,
                                SHA1 = cutSHA1,
                                Width = thum.Width,
                                Height = thum.Height
                            };
                            _bucketImagesService.insertImage(entity);
                            return imageResult(ms, item.FileName);
                        }
                    }
                    return imageResult(thum, item.FileName);
                }
            }
            catch (Exception)
            {
                return HttpNotFound();
            }
        }

        /// <summary>
        /// 最终返回图片结果
        /// </summary>
        /// <param name="image"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private FileResult imageResult(Image image, string fileName)
        {
            string contentType = "image/jpeg";
            var ms = imageSave(image, fileName);
            ImageFormat format = ImageFormat.Jpeg;
            switch (Path.GetExtension(fileName).ToLower())
            {
                case ".jpg":
                case ".jpeg":
                    contentType = "image/jpeg";
                    break;
                case ".png":
                    format = ImageFormat.Png;
                    contentType = "image/png";
                    break;
                case ".gif":
                    format = ImageFormat.Gif;
                    contentType = "image/gif";
                    break;
            }
            return File(ms.ToArray(), contentType);
        }
        /// <summary>
        /// 最终返回图片结果
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private FileResult imageResult(MemoryStream ms, string fileName)
        {
            string contentType = getContentType(fileName);
            return File(ms.ToArray(), contentType);
        }

        /// <summary>
        /// 获取图片响应的 ContentType
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private string getContentType(string fileName)
        {
            string contentType = "image/jpeg";
            switch (Path.GetExtension(fileName).ToLower())
            {
                case ".jpg":
                case ".jpeg":
                    contentType = "image/jpeg";
                    break;
                case ".png":
                    contentType = "image/png";
                    break;
                case ".gif":
                    contentType = "image/gif";
                    break;
            }
            return contentType;
        }

        /// <summary>
        /// 图片保存为内存流
        /// MemoryStream 未using
        /// </summary>
        /// <param name="image"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private MemoryStream imageSave(Image image, string fileName)
        {
            ImageFormat format = ImageFormat.Jpeg;
            MemoryStream ms = new MemoryStream();
            switch (System.IO.Path.GetExtension(fileName).ToLower())
            {
                case ".jpg":
                case ".jpeg":
                    break;
                case ".png":
                    format = ImageFormat.Png;
                    break;
                case ".gif":
                    format = ImageFormat.Gif;
                    break;
            }
            image.Save(ms, format);
            return ms;
        }


        /// <summary>
        /// 处理缩略图
        /// resize=w_150
        /// reisze=h_150
        /// //
        /// </summary>
        /// <param name="image"></param>
        /// <param name="resize"></param>
        /// <returns></returns>
        private Image processSize(Image image, string resize)
        {
            ThumbnailProportion pro = ThumbnailProportion.WIDTH;
            int width = 0;
            int height = 0;
            if (resize.IndexOf(',') == -1)
            {
                if (resize.StartsWith("h_"))
                {
                    string value = Regex.Replace(resize, @"[^0-9]*", "");
                    int.TryParse(value, out height);
                    pro = ThumbnailProportion.HEIHT;
                }
                else if (resize.StartsWith("w_"))
                {
                    string value = Regex.Replace(resize, @"[^0-9]*", "");
                    int.TryParse(value, out width);
                    pro = ThumbnailProportion.WIDTH;
                }
            }
            else
            {
                var resizeArr = resize.ToLower().Split(',');
                foreach (var temp in resizeArr)
                {
                    switch (temp)
                    {
                        case "m_fill":
                            pro = ThumbnailProportion.CUT;
                            break;
                        case "m_fixed":
                            pro = ThumbnailProportion.WIDTH_HEIHT;
                            break;
                        case "m_h":
                            pro = ThumbnailProportion.HEIHT;
                            break;
                        case "m_w":
                            pro = ThumbnailProportion.WIDTH;
                            break;
                        default:
                            if (temp.StartsWith("h_"))
                            {
                                string value = Regex.Replace(temp, @"[^0-9]*", "");
                                int.TryParse(value, out height);
                            }
                            else if (temp.StartsWith("w_"))
                            {
                                string value = Regex.Replace(temp, @"[^0-9]*", "");
                                int.TryParse(value, out width);
                            }
                            break;
                    }
                }
            }
            return ImageUitls.getThumbnail(image, pro, width, height);
        }

        /// <summary>
        /// 处理水印
        /// </summary>
        /// <param name="image">图片</param>
        /// <param name="bucket">bucket</param>
        /// <param name="watermark">参数指示是否打水印。1：天添加水印</param>
        /// <returns></returns>
        private Image waterMarkImage(Image image, string bucket, string watermark)
        {
            var bucketItem = _bucketService.getByName(bucket);
            if (bucketItem == null)
                return image;
            var appItem = _appStorageService.getById(bucketItem.AppStorageId);
            if (appItem == null)
                return image;
            if (String.IsNullOrEmpty(watermark) || !watermark.Equals("1"))
                return image;

            switch (appItem.WaterType)
            {
                case (int)EnumWaterType.图片水印:
                    return ImageUitls.waterMarkPicture(image, new Bitmap(new MemoryStream(appItem.WaterImage)), (WaterPosition)appItem.Position, appItem.Opacity);
                case (int)EnumWaterType.文字水印:
                    return ImageUitls.waterMarkText(image, appItem.FontText, appItem.FontFamily, appItem.FontSize, appItem.FontColor, (WaterPosition)appItem.Position, appItem.Opacity, appItem.FontRotate);
            }
            return image;
        }



        #endregion

    }
}